home *** CD-ROM | disk | FTP | other *** search
- #if defined(NOASM) || \
- defined(USE_ZBUFFER) || \
- !( \
- ((defined(__mc68020__) || defined(__mc68030__)) && defined(__HAVE_68881__)) || \
- defined(__mc68040__) || \
- defined(__mc68060__) \
- )
- # undef NOASM
- # define NOASM
- # undef staticvar
- # define staticvar
- #endif
-
- /* clipping */
- static point_3d defaultPoints[32], *defaultVList[32];
- staticvar fix scan[768][2];
-
- void setup_default_point_list(void)
- {
- int i;
-
- for (i = 32 - 1; i >= 0; --i)
- defaultVList[i] = &defaultPoints[i];
- }
-
- /* calculation */
- static short int compute_mip_level(__memBase, int face)
- {
- /*
- * dumb algorithm: grab 3d coordinate of some vertex,
- * compute dist from viewer
- */
- double dist;
- int se = bspMem->shared.quake1.dfaces[face].firstedge;
- int e = bspMem->shared.quake1.dsurfedges[se];
-
- if (e < 0)
- e = -e;
- dist = scalw(dist2_from_viewer((vec_t *) & bspMem->shared.quake1.dvertexes[bspMem->shared.quake1.dedges[e].v[0]].point), -16); /* / 65536; */
- if (dist < 1)
- return 0;
- if (dist < 4)
- return 1;
- if (dist < 16)
- return 2;
- return 3;
- }
-
- staticvar float tmap[9];
-
- static void compute_texture_gradients(__memBase, struct texture *Text, short int mip)
- {
- float uu, vv;
- float tmp0, tmp1, tmp2;
- vec3_t P, M, N;
-
- /* project vectors onto face's plane, and transform */
- transform_vector(M, Text->textGradient.uv0);
- transform_vector(N, Text->textGradient.uv1);
- transform_point_raw(P, Text->textGradient.scaled);
-
- uu = Text->textGradient.u;
- vv = Text->textGradient.v;
-
- /*
- * we could just subtract (u,v) every time we compute a new (u,v);
- * instead we fold it into P:
- */
- P[0] += uu * M[0] + vv * N[0];
- P[1] += uu * M[1] + vv * N[1];
- P[2] += uu * M[2] + vv * N[2];
-
- /*
- * offset by Center of screen--if this were folded into
- * transform translation we could avoid it
- */
- tmp2 = N[0] * M[2] - N[2] * M[0];
- tmp1 = N[1] * M[2] - N[2] * M[1];
- tmp0 = N[0] * M[1] - N[1] * M[0];
- tmp0 -= tmp1 * xCenter + tmp2 * yCenter;
- tmap[8] = tmp2;
- tmap[7] = tmp1;
- tmap[6] = tmp0;
-
- tmp2 = P[2] * M[0] - P[0] * M[2];
- tmp1 = P[2] * M[1] - P[1] * M[2];
- tmp0 = P[1] * M[0] - P[0] * M[1];
- tmp0 -= tmp1 * xCenter + tmp2 * yCenter;
- tmap[5] = scalw(tmp2, -mip);
- tmap[4] = scalw(tmp1, -mip);
- tmap[3] = scalw(tmp0, -mip);
-
- tmp2 = P[0] * N[2] - P[2] * N[0];
- tmp1 = P[1] * N[2] - P[2] * N[1];
- tmp0 = P[0] * N[1] - P[1] * N[0];
- tmp0 -= tmp1 * xCenter + tmp2 * yCenter;
- tmap[2] = scalw(tmp2, -mip);
- tmap[1] = scalw(tmp1, -mip);
- tmap[0] = scalw(tmp0, -mip);
- }
-
- /*
- * NOTE: subdivision of 16 is a really hard thig, it works most, but you can see sometimes curved textures
- * if you have some processorpower use 8 instead!
- */
- #define SUBDIV_SHIFT 4
- #define SUBDIV (1 << SUBDIV_SHIFT)
- #define SUBDIV_MASK (SUBDIV - 1)
-
- /* draw an affine (linear) span starting at dest, n pixels long, */
- /* starting at (u,v) in the texture and stepping by (du,dv) each pixel */
- /*
- * if we are in liquid, we can calculate the average pixelcolor
- * of the liquid texture (eg. *lava1) and do a transp with this color
- * so we don't need to change the palette, and the accuracity
- * is better
- *
- * we can make the liquid with a falloff if we use the zbuffer,
- * we have the current z-value, and the z-value at that position
- * we sub them and calculate the transparency-level from that
- * (better use every 10th or like that transparency-level: first,
- * the transparency is not so accurate, that every percent makes
- * a change, second, all 100% transparency uses 6,5MB cached
- * tables, both in memory and on disk (horror!))
- * the falloff is calculated from the brightness of the liquid texture
- * and the type, so brighter texture are more transparent than darker
- *
- * the liquid looks more real if the textures after it also warps
- * so we must determine, which textures lies in liquid, probably
- * we can use the same procedure as the liquid itself, maybe
- * we must project the liquids behaviour to the texture (uff)
- *
- * how to determine if a texture lies in liquid? as I know qbsp
- * splits the plaes at every intersection of two polygons, that
- * means we do not need to split the polygon at the liquid-line
- * the disadvatage of the mark-texture-in-liquid is, that while
- * we are in liquid, the textures outside the liquid doesn't warp
- *
- * probably we can do real wave in liquid, for that we do not change
- * the du or dv, but the z-value (upwards) of the polygon in a
- * reproducable caustics manner, the difficulty is, to calculate this
- * values in the very inner loop (draw_affine), thats slow
- *
- * how to avoid this mipmap shiftig and masking in liquid textures:
- * after building the waterblock convert the scanlines from this:
- *
- * +----+ example: memory-block-size is 64*64
- * |****| mipmap-size is 32*32
- * | | memory is linear
- * | |
- * | |
- * +----+
- *
- * interally handled as this: to this:
- *
- * +--+ +----+ we need no shiftig, on masking
- * |**| |** | and it is faster, 'cause the
- * |**| |** | conversion could be cached and is
- * +--+ | | out of the span-draw-inner-loop
- * | |
- * +----+
- *
- * we can even remove all the shifting, if we put the warp-textures
- * in a 256*64 block, so the offset is 0x0000xxyy (0b000000000000000000xxxxxx00yyyyyy)
- * that is a 16k-block per watertexture, not too much
- *
- * probably it could be faster, if we call a hook defined in the TextureCache
- */
-
- #ifndef NOASM
- #ifdef DRIVER_8BIT
- #include "drawSpans8-m68k2.S"
- #include "drawSpans8flat-m68k2.S"
- #include "drawSpans8wire-m68k2.S"
- #endif
- #ifdef DRIVER_16BIT
- #include "drawSpans16-m68k2.S"
- #endif
- #ifdef DRIVER_24BIT
- #include "drawSpans24-m68k2.S"
- #endif
- #ifdef DRIVER_32BIT
- #include "drawSpans32-m68k2.S"
- #endif
- #else
- #ifdef DRIVER_8BIT
- #include "draw-opti8.c"
- #include "draw-opti8flat.c"
- #include "draw-opti8wire.c"
- #endif
- #ifdef DRIVER_16BIT
- #include "draw-opti16.c"
- #endif
- #ifdef DRIVER_24BIT
- #include "draw-opti24.c"
- #endif
- #ifdef DRIVER_32BIT
- #endif
- #endif
-
- /* preparing */
- static inline void scan_convert(point_3d * a, point_3d * b)
- {
- int right;
- fix x, dx;
- int y, ey;
-
- if (a->sy == b->sy)
- return;
-
- if (a->sy < b->sy)
- right = 0;
- else {
- void *temp = a;
-
- a = b;
- b = temp;
- right = 1;
- }
-
- /* compute dxdy */
- dx = FLOAT_TO_INT(scalw((b->sx - a->sx), 16) / (b->sy - a->sy)); /* * 65536.0 */
- x = a->sx;
- y = FIX_INT(a->sy);
- ey = FIX_INT(b->sy);
- x += FLOAT_TO_INT(((double)dx * ((y << 16) - a->sy)) * (1 / 65534.0));
-
- while (y < ey) {
- scan[y][right] = FIX_INT(x);
- x += dx;
- ++y;
- }
- }
-